package castledefense.game.render;

import castledefense.data.GameData;
import castledefense.game.screens.MainGameScreen;
import castledefense.logic.Map;

import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Matrix4;

public class Cam {

	public static final Matrix4 normalProjection = new Matrix4();
	private static final int maxTranslate = MainGameScreen.mapSizeX
			* Map.cellWidth;
	private final static float translateSpeed = 0.6f;
	private static float maxZoom = 0f;
	private static float minZoom = 0.35f;
	
	public static final OrthographicCamera camera = new OrthographicCamera();
	static {
		camera.position.set(MainGameScreen.mapSizeX / 2 * Map.cellWidth,
				MainGameScreen.mapSizeX / 2 * Map.cellWidth, 0);		
		camera.direction.set(0, 0, -1);
		camera.up.set(0, 1, 0);
		// Following code is only needed if screen width is smaller than screen
		// height.
		// this calculate maxZoom factor for any aspect ratio or windows size.
		int tmp = GameData.SCREENSIZEX;
		if (tmp < GameData.SCREENSIZEY) {
			maxZoom = ((float)(MainGameScreen.mapSizeX + 2) * Map.cellWidth)  /(float) GameData.SCREENSIZEX;
		}
		if (GameData.SCREENSIZEX > GameData.SCREENSIZEY) {
			maxZoom = ((float)(MainGameScreen.mapSizeY + 2) * Map.cellWidth)  /(float) GameData.SCREENSIZEY;
		}
	}
	
	public static float getCameraBottomLeftX(){
		return camera.position.x - GameData.HALFSCREENSIZEX;
	}
	
	public static float getCameraBottomLeftY(){
		return camera.position.y - GameData.HALFSCREENSIZEY;
	}

	public static final void update() {
		camera.update();
	}

	public static final Matrix4 getMatrix() {
		camera.update();
		return camera.combined;
	}

	public static final float getZoom() {
		return camera.zoom;
	}

	public static final void moveRight(float delta) {
		camera.translate(translateSpeed * delta*camera.zoom, 0, 0);
		checkX();
	}

	public static final void moveLeft(float delta) {
		camera.translate(-translateSpeed * delta*camera.zoom, 0, 0);
		checkX();
	}

	public static final void moveUp(float delta) {
		camera.translate(0, translateSpeed * delta*camera.zoom, 0);
		checkY();
	}

	public static final void moveDown(float delta) {
		camera.translate(0, -translateSpeed * delta*camera.zoom, 0);
		checkY();
	}

	private static final void checkX() {
		if (camera.position.x < camera.zoom*(GameData.HALFSCREENSIZEX-190))
			camera.position.x = camera.zoom*(GameData.HALFSCREENSIZEX-190);			
			if (camera.position.x > maxTranslate - camera.zoom*(GameData.HALFSCREENSIZEX-30))
			camera.position.x = maxTranslate - camera.zoom*(GameData.HALFSCREENSIZEX-30);

	}

	private static final void checkY() {
		if (camera.position.y < camera.zoom*(GameData.HALFSCREENSIZEY-10))
			camera.position.y = camera.zoom*(GameData.HALFSCREENSIZEY-10);
		if (camera.position.y > maxTranslate- camera.zoom*(GameData.HALFSCREENSIZEY-10))
			camera.position.y = maxTranslate- camera.zoom*(GameData.HALFSCREENSIZEY-10);
	}

	public static final void zoom(float amount) {
		camera.zoom += amount;
		if (camera.zoom < minZoom) {
			camera.zoom = minZoom;
		} else if (camera.zoom > maxZoom) {
			camera.zoom = maxZoom;
		}
	}

	public static final void zoom(float amount, float toX, float toY) {
		float oldZ = camera.zoom;
		camera.zoom += amount;
		// If zooming still has effect then we need translate map towards cursor
		if (camera.zoom < minZoom) {
			camera.zoom = minZoom;
		} else if (camera.zoom > maxZoom) {
			camera.zoom = maxZoom;
		} else {
			float a = (toX - (float) GameData.HALFSCREENSIZEX)
					* (oldZ - camera.zoom);
			float b = (-toY + (float) GameData.HALFSCREENSIZEY)
					* (oldZ - camera.zoom);
			camera.translate(a, b, 0);
			checkX();
			checkY();
		}
	}

	public static final void move(float x, float y) {
		camera.translate(x*camera.zoom, -y*camera.zoom, 0);
		checkX();
		checkY();
	}
	
	public static final void checkPosition(){
		checkX();
		checkY();
	
	}
	public static final void setPosition(float x, float y) {
		camera.position.set(x, -y, 0);
		checkX();
		checkY();
	}
}